home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Netware Super Library
/
Netware Super Library.iso
/
printing
/
select14
/
select.cpp
< prev
next >
Wrap
Text File
|
1992-10-22
|
20KB
|
967 lines
#include <stdio.h>
#include <conio.h>
#include <dos.h>
#include <dir.h>
#include <string.h>
#include <mem.h>
#include <stdlib.h>
#include <graphics.h>
#include <ctype.h>
typedef unsigned char BYTE;
typedef unsigned int WORD;
typedef unsigned long LONG;
#define zap(a) {memset ( &a, NULL, sizeof(a));}
#define MaxLines 20
struct scanBindReq {
WORD Length;
BYTE Function;
LONG LastObjectID;
WORD ObjectType;
BYTE ObjectNameLength;
BYTE ObjectName[48];
};
struct scanBindRep {
WORD Length;
LONG ObjectID;
WORD ObjectType;
BYTE ObjectName[48];
BYTE ObjectFlag;
BYTE ObjectSecurity;
BYTE ObjectHasProperties;
};
struct readPropValueReq {
WORD Length;
BYTE Function;
WORD ObjectType;
BYTE ObjectNameLength;
BYTE ObjectName[48];
BYTE SegmentNumber;
BYTE PropertyNameLength;
BYTE PropertyName[16];
};
struct readPropValueRep {
WORD Length;
BYTE PropertyValue[128];
BYTE MoreSegments;
BYTE PropertyFlags;
};
struct readQueueStatReq {
WORD Length;
BYTE Function;
LONG ObjectID;
};
struct readQueueStatRep {
WORD Length;
LONG ObjectID;
BYTE QueueStatus;
BYTE NumberOfJobs;
BYTE NumberOfServers;
LONG ServerID[25];
BYTE ServerStation[25];
BYTE MaxServers;
};
struct getBindObjNameReq {
WORD Length;
BYTE Function;
LONG ObjectID;
};
struct getBindObjNameRep {
WORD Length;
LONG ObjectID;
WORD ObjectType;
BYTE ObjectName[48];
};
char ProgName[]="Select";
int VerMaj=1;
int VerMin=4;
char ENET[]="000000000000";
char *ptr;
FILE *LocationSrt;
char DefQ[48];
char qlst[100][100];
char qloc[100][100];
int qrdy[100];
int qcnt=0;
int MaxQueueNameLength=0;
int MaxServerNameLength=0;
int Banner=1;
int LptNum=1;
int timeout=30;
int xl,xh,yl,yh;
char *qstat[]={ " <Off> ",
"Available",
" Default ",
" Local "};
int API_E3(void *Request, void *Reply)
{
_SI=(unsigned)Request;
_DI=(unsigned)Reply;
_ES=_DS;
_AH=0xE3;
geninterrupt(0x21);
return(_AL);
}
void pause()
{
getch();
}
void perror(int ern)
{
switch (ern)
{
case 0x00: printf("Success\n"); break;
case 0x96: printf("Server Out Of Memory\n"); break;
case 0x9C: printf("Invalid Path\n"); break;
case 0xD0: printf("Q Error\n"); break;
case 0xD1: printf("No Queue\n"); break;
case 0xD2: printf("No Q Server\n"); break;
case 0xD3: printf("No Q Rights\n"); break;
case 0xD5: printf("No Q Job\n"); break;
case 0xEC: printf("No Such Segment\n"); break;
case 0xEF: printf("Invalid name\n"); break;
case 0xF0: printf("Wildcard Not Allowed\n"); break;
case 0xF1: printf("Invalid Bindary Security\n"); break;
case 0xFB: printf("No Such Property\n"); break;
case 0xFC: printf("No Such Object\n"); break;
case 0xFE: printf("Server Bindary Locked\n"); break;
case 0xFF: printf("Bindary Failure\n"); break;
default: printf("Unknown error #%2x#2\n",ern); break;
}
}
int ScanBinderyObject (char *searchObjectName, WORD searchObjectType,
long *objectID, char *objectName, WORD *objectType,
char *objectHasProperties, char *objectFlag,
char *objectSecurity)
{
static long Last_ObjectID=0xFFFFFFFF;
struct scanBindReq Request;
struct scanBindRep Reply;
int result;
// memset ( & Request, NULL, sizeof(Request));
// memset ( & Reply, NULL, sizeof(Reply ));
zap(Request);
zap(Reply);
Request.Length= sizeof(Request)-2;
Request.Function= 0x37;
Request.LastObjectID= Last_ObjectID;
Request.ObjectType= searchObjectType;
Request.ObjectNameLength=strlen(searchObjectName);
strcpy(Request.ObjectName,searchObjectName);
Reply.Length=sizeof(Reply)-2;
result=API_E3(&Request,&Reply);
*objectID =Reply.ObjectID;
strcpy(objectName,Reply.ObjectName);
*objectType =Reply.ObjectType;
*objectHasProperties=Reply.ObjectHasProperties;
*objectFlag =Reply.ObjectFlag;
*objectSecurity =Reply.ObjectSecurity;
Last_ObjectID=*objectID;
return (result);
}
void GetPrintServerName(long qsid,char *sname)
{
struct getBindObjNameReq Request;
struct getBindObjNameRep Reply;
int result;
zap(Request);
zap(Reply);
Request.Length= sizeof(Request)-2;
Request.Function=0x36;
Request.ObjectID=qsid;
Reply.Length= sizeof(Reply )-2;
result=API_E3(&Request,&Reply);
if (result>0) {
perror(result);
strcpy(sname,"");
}
else {
strcpy(sname,Reply.ObjectName);
}
return;
}
void GetPrintServer (long qid,char *sname)
{
struct readQueueStatReq Request;
struct readQueueStatRep Reply;
int result;
zap(Request);
zap(Reply);
Request.Length=sizeof(Request)-2;
Request.Function=0x66;
Request.ObjectID=qid;
Reply.Length= sizeof(Reply )-2;
result=API_E3(&Request,&Reply);
if (result!=0) perror(result);
if (Reply.NumberOfServers>0) {
GetPrintServerName(Reply.ServerID[0],sname);
}
else {
strcpy(sname,"");
}
return;
}
void GetQueueLocation(LONG qid,char *qloc)
{
struct readPropValueReq Request;
struct readPropValueRep Reply;
int result;
char sname[100];
zap(Request);
zap(Reply);
zap(sname);
GetPrintServer(qid,sname);
Request.Length=sizeof(Request)-2;
Request.Function=0x3D;
Request.ObjectType=0x0700; // 0x0700 = Queue (Byte swapped)
Request.ObjectNameLength=sizeof(Request.ObjectName);
strcpy(Request.ObjectName,sname);
Request.SegmentNumber=1;
Request.PropertyNameLength=14;
strcpy(Request.PropertyName,"IDENTIFICATION");
Reply.Length=sizeof(Reply)-2;
if (sname[0]=='\0')
{
result=0;
}
else
{
result=API_E3(&Request,&Reply);
}
if (result!=0) {
perror(result);
strcpy(qloc,"");
}
else strcpy(qloc,Reply.PropertyValue);
return;
}
void GetServerLocation(LONG qsid, char *qloc)
{
struct readPropValueReq Request;
struct readPropValueRep Reply;
int result;
char stmp[100];
zap(Request);
zap(Reply);
zap(stmp);
GetPrintServerName(qsid,stmp);
Request.Length=sizeof(Request)-2;
Request.Function=0x3D;
Request.ObjectType=0x0700; // 0x0700 = Queue (Byte swapped)
Request.ObjectNameLength=sizeof(Request.ObjectName);
strcpy(Request.ObjectName,stmp);
Request.SegmentNumber=1;
Request.PropertyNameLength=14;
strcpy(Request.PropertyName,"IDENTIFICATION");
Reply.Length=sizeof(Reply)-2;
result=API_E3(&Request,&Reply);
if (result!=0)
{
perror(result);
strcpy(qloc,"");
}
else strcpy(qloc,Reply.PropertyValue);
return;
}
void GetQueueDefaultLocation(char *qname, char *qloc)
{
struct readPropValueReq Request;
struct readPropValueRep Reply;
int result;
union
{
char s[4];
LONG l;
} PServer;
zap(Request);
zap(Reply);
Request.Length=sizeof(Request)-2;
Request.Function=0x3D;
Request.ObjectType=0x0300; // 0x0300 = Print Queue (Byte swapped)
Request.ObjectNameLength=sizeof(Request.ObjectName);
strcpy(Request.ObjectName,qname);
Request.SegmentNumber=1;
Request.PropertyNameLength=9;
strcpy(Request.PropertyName,"Q_SERVERS");
Reply.Length=sizeof(Reply)-2;
result=API_E3(&Request,&Reply);
if (result!=0) {
if (result!=0xFC) perror(result);
strcpy(qloc,"");
}
else
{
PServer.s[0]=Reply.PropertyValue[0];
PServer.s[1]=Reply.PropertyValue[1];
PServer.s[2]=Reply.PropertyValue[2];
PServer.s[3]=Reply.PropertyValue[3];
GetServerLocation(PServer.l,qloc);
}
return;
}
int QueueServerReady (long qid)
{
struct readQueueStatReq Request;
struct readQueueStatRep Reply;
int result;
zap(Request);
zap(Reply);
Request.Length=sizeof(Request)-2;
Request.Function=0x66;
Request.ObjectID=qid;
Reply.Length= sizeof(Reply )-2;
result=API_E3(&Request,&Reply);
if (result!=0) perror(result);
result=0;
if (Reply.NumberOfServers>0) result=1;
return (result);
}
void GetDefaultQueue()
{
char *s1;
char *s2;
char s[100];
int t;
strcpy(qlst[qcnt],"NONE");
strcpy(qloc[qcnt],"Local printer");
qrdy[qcnt]=3;
qcnt++;
ptr = getenv("PATH");
s1=ptr;
s2=ptr;
while (*s1!=NULL)
{
while ((*s2!=NULL)&&(*s2!=';')) s2++;
if (*s2==';')
{
*s2=NULL;
strcpy(s,s1);
*s2=';';
s2++;
}
else
{
strcpy(s,s1);
}
s1=s2;
s2++;
strcat(s,"\\LOCATION.SRT");
LocationSrt=fopen(s,"rt");
if (LocationSrt!=NULL) break;
}
strcpy(DefQ,"NONE");
if (LocationSrt==NULL) return;
t=1;
while (t==1)
{
if (fgets(s,sizeof(s),LocationSrt)==NULL)
{
fclose(LocationSrt);
strcpy(DefQ,"NONE");
return;
}
if (strlen(s)<20)
{
fclose(LocationSrt);
strcpy(DefQ,"NONE");
return;
}
s1=(char *)&s;
s2=s1;
while (*s1!=' ') s1++;
while ((s1>s2)&&(*s1!=':')) s1--;
if (*s1==':') s1++;
while (*s2!=' ') s2++;
*s2=NULL;
t=strcmp(ENET,s1);
*s2=' ';
if (t==0)
{
s2++;
for (t=32;t>0;t--) s2++;
s2++;
s1=(char *)&DefQ;
while ((*s2!=' ')&&(*s2!='\n')) *(s1++)=*(s2++);
*s1=NULL;
}
if (t!=0) t=1;
}
fclose(LocationSrt);
strcpy(qlst[qcnt],DefQ);
strcpy(qloc[qcnt],"Normal network location");
qrdy[qcnt]=2;
qcnt++;
}
void GetEthernetNumber()
{
union REGS regs;
regs.h.ah = 0xEE;
intdos(®s, ®s);
sprintf(ENET,"%04X%04X%04X",regs.x.cx,regs.x.bx,regs.x.ax);
}
void LoadList()
{
BYTE searchObjectName[48]="*";
WORD searchObjectType=0x0300; // 0x0300 = Print Queue
long objectID;
BYTE objectName[48];
WORD objectType;
BYTE objectHasProperties;
BYTE objectFlag;
BYTE objectSecurity;
int result;
result=0;
while (result==0)
{
result=ScanBinderyObject (
searchObjectName, searchObjectType, &objectID, objectName,
&objectType, &objectHasProperties, &objectFlag,
&objectSecurity);
if (result!=0 && result!=0xFC) perror(result);
if (qcnt<100-1 && result==0)
{
qrdy[qcnt]=QueueServerReady(objectID);
strcpy(qlst[qcnt],objectName);
GetQueueLocation(objectID,qloc[qcnt]);
if (*qloc[qcnt]==NULL)
{
GetQueueDefaultLocation(objectName,qloc[qcnt]);
}
qcnt++;
}
}
}
void SortList()
{
char tstr[100];
int i,j,t;
for (i=0;i<qcnt-1;i++)
{
for (j=i+1;j<qcnt;j++)
{
if (strcmp(qlst[i],qlst[j])>0)
{
strcpy(tstr,qlst[i]);
strcpy(qlst[i],qlst[j]);
strcpy(qlst[j],tstr);
strcpy(tstr,qloc[i]);
strcpy(qloc[i],qloc[j]);
strcpy(qloc[j],tstr);
t=qrdy[i]; qrdy[i]=qrdy[j]; qrdy[j]=t;
}
}
}
}
int getArrow()
{
char ch;
ch=' ';
while (ch==' ')
{
ch=getch();
if (ch==0x000D) {ch='s'; break;} // Return
if (ch==0x001B) {ch='e'; break;} // Escape
if (ch==0x0018) {ch='X'; break;} // Ctl-X
if (ch==0x0042) {ch='b'; break;} // 'B'
if (ch==0x0062) {ch='b'; break;} // 'b'
if (ch==0x0031) {ch='1'; break;} // '1'
if (ch==0x0032) {ch='2'; break;} // '2'
if (ch==0x0033) {ch='3'; break;} // '3'
if (ch==0X003F) {ch='?'; break;} // '?'
if (ch==0x0058) {ch='X'; break;} // 'X'
if (ch==0x0078) {ch='X'; break;} // 'x'
if (ch==0x002B) {ch='+'; break;} // '+'
if (ch==0x002D) {ch='-'; break;} // '-'
if (ch==0x0000) // Extended key as follows:
{
ch=getch();
if (ch==0x0047) {ch='H'; break;} // Home
if (ch==0x0048) {ch='u'; break;} // Up
if (ch==0x0049) {ch='U'; break;} // PgUp
if (ch==0x004F) {ch='E'; break;} // End
if (ch==0x0050) {ch='d'; break;} // Down
if (ch==0x0051) {ch='D'; break;} // PgDn
if (ch==0x003B) {ch='?'; break;} // F1 (Help)
if (ch==0x002D) {ch='X'; break;} // Alt-X
}
ch=' ';
}
return (ch);
}
void ShowQ(int i, int j)
{
int t;
if (j==0)
{
textcolor(WHITE);
textbackground(BLUE);
}
t=xh-xl-1-MaxQueueNameLength-MaxServerNameLength;
cprintf("%-*s %-*s %*s",MaxQueueNameLength,qlst[i],
MaxServerNameLength,qloc[i],
t,qstat[qrdy[i]]);
textcolor(LIGHTGRAY);
textbackground(BLACK);
}
int ShowUpdate(int WinTop, int WinPos)
{
static OldTop=-2;
static OldPos=-2;
int i,j;
REGS scroll;
if (OldTop==WinTop)
{
gotoxy(xl,2+OldPos-OldTop);
ShowQ(OldPos,1);
gotoxy(xl,2+WinPos-WinTop);
ShowQ(WinPos,0);
}
else
if (OldTop-WinTop==1)
{
gotoxy(xl,2+OldPos-OldTop);
ShowQ(OldPos,1);
zap(scroll);
scroll.h.ah=0x07;
scroll.h.al=1;
scroll.h.bh=BLACK<<4+LIGHTGRAY;
scroll.h.ch=yl-1;
scroll.h.cl=xl-1;
scroll.h.dh=yh-1;
scroll.h.dl=xh-1;
int86(0x10,&scroll,&scroll);
gotoxy(xl,yh);
gotoxy(xl,2+WinPos-WinTop);
ShowQ(WinPos,0);
}
else
if (WinTop-OldTop==1)
{
gotoxy(xl,2+OldPos-OldTop);
ShowQ(OldPos,1);
zap(scroll);
scroll.h.ah=0x06;
scroll.h.al=1;
scroll.h.bh=BLACK<<4+LIGHTGRAY;
scroll.h.ch=yl-1;
scroll.h.cl=xl-1;
scroll.h.dh=yh-1;
scroll.h.dl=xh-1;
int86(0x10,&scroll,&scroll);
gotoxy(xl,yl);
gotoxy(xl,2+WinPos-WinTop);
ShowQ(WinPos,0);
}
else
{
j=qcnt-1;
if (j>MaxLines) j=MaxLines;
for (i=0; i<j; i++)
{
gotoxy(xl,2+i);
ShowQ(WinTop+i,WinTop+i-WinPos);
}
}
gotoxy(xl-1,2);
cprintf("%s",(WinTop>0)?"":"║");
gotoxy(xl-1,MaxLines+1);
cprintf("%s",(WinTop+MaxLines<qcnt)?"":"║");
gotoxy(xl,yh+2);
cprintf("<ESC> to Exit, <CR> to Select, B for %s",
Banner==0?"no banner":"a banner ");
gotoxy(xl,yh+3);
cprintf("1=LPT1, 2=LPT2, 3=LPT3: <%d> ±=Timeout %3d",LptNum,timeout);
gotoxy(1,1);
OldTop=WinTop;
OldPos=WinPos;
return getArrow();
}
void ShowList()
{
// ╚╔╩╦╠═╣║╗╝
// │┤┐└┴┬├─┼
int i,j,o;
o=(80-MaxQueueNameLength-MaxServerNameLength-strlen(qstat[0])) / 2;
if (o>17) o=17;
j=qcnt;
if (j>MaxLines) j=MaxLines;
xl=o+1;
yl=2;
xh=xl+80-o-o;
yh=yl+j-1;
clrscr();
gotoxy(o,1);
cprintf("╔");
for (i=1; i<(82-o-o); i++) cprintf("═");
cprintf("╗");
for (i=0; i<j; i++)
{
gotoxy(xl-1,2+i);
cprintf("║");
ShowQ(i,i);
gotoxy(xh+1,2+i);
cprintf("║");
}
if (j>=MaxLines)
{
gotoxy(xl-1,j+1);
cprintf("");
}
gotoxy(o,j+2);
cprintf("╠");
for (i=1; i<(82-o-o); i++) cprintf("═");
cprintf("╣");
gotoxy(o,j+3);
cprintf("║");
for (i=1; i<(82-o-o); i++) cprintf(" ");
cprintf("║");
gotoxy(o,j+4);
cprintf("║");
for (i=1; i<(82-o-o); i++) cprintf(" ");
cprintf("║");
gotoxy(o,j+5);
cprintf("╚");
for (i=1; i<(82-o-o); i++) cprintf("═");
cprintf("╝");
gotoxy(o+1,j+3);
cprintf("<ESC> to Exit, <CR> to Select, B for %sbanner",
Banner==0?"no ":"a ");
gotoxy(o+1,j+4);
cprintf("1=LPT1, 2=LPT2, 3=LPT3: <%d> ±=Timeout %3d",LptNum,timeout);
gotoxy(1,j+5);
return;
}
void SelectQueue(int i)
{
char stmp[100];
strcpy(stmp,"");
if (i==-2) i=qcnt-2;
if (i==-3) i=qcnt-1;
if (i==qcnt-1) // reset
{
if (strcmp("NONE",qlst[i])==0) i--; // reset IS none
Banner=0; // reset already has banner defined
}
if (i==qcnt-2) // none
{
sprintf(stmp,"ENDCAP");
}
if (i==-1)
{
sprintf(stmp,"CAPTURE /SHOW");
}
if ((i>=0)&&(i<qcnt))
{
sprintf(stmp,"CAPTURE /Q=%s%s /NT /TI=%d /L=%d",
qlst[i],Banner>0?" /NB":"",timeout,LptNum);
}
normvideo();
if (_argc==1) clrscr();
system(stmp);
return;
}
void usage()
{
printf("%s v%d.%d\n",ProgName,VerMaj,VerMin);
printf("Created by Jeff Pilant <pilant@nadc.nadc.navy.mil>\n");
printf("\n");
printf("Usage:\n");
printf("\n");
printf(" SELECT <queue> [/NB] | <keyword> | FILE <filename>\n");
printf("\n");
printf("Where:\n");
printf(" <queue> is the name of a print queue\n");
printf(" /NB selects no banner\n");
printf(" HELP this text\n");
printf(" RESET reset to login setup\n");
printf(" LPT set for no capturing of printers\n");
printf(" NONE set for no capturing of printers\n");
printf(" LOCAL set for no capturing of printers\n");
printf(" SHOW display capture status\n");
printf(" FILE set for capture to file <filename>\n");
printf(" the captured file must reside on the server\n");
printf("\n");
printf("With no arguments, select give a menu and allows you to\n");
printf("set the timeout and choose queues for lpt2 and lpt3 as well.\n");
exit (0);
return;
}
void SetFile(char *fn)
{
char stmp[100];
zap(stmp);
sprintf(stmp,"CAPTURE /CR=%s /TI=300 /NT /NFF /NB",fn);
system(stmp);
exit(0);
}
void UseArg()
{
char *kw[]={"HELP","?","/?","RESET","LPT","NONE","LOCAL","SHOW","FILE",""};
int i;
int reset=0;
int help=0;
int local=0;
int show=0;
char *ch;
ch=_argv[1];
while (*ch!=NULL) {*ch=toupper(*ch); ch++;}
Banner=0; // default command line entry to banner
if (_argc==3)
{
ch=_argv[2];
while (*ch!=NULL) {*ch=toupper(*ch); ch++;}
if (strcmp("/NB",_argv[2])==0) Banner=1;
if (strcmp("NB",_argv[2])==0) Banner=1;
if (Banner==0)
{
if (strcmp(_argv[1],kw[8])==0)
{
SetFile(_argv[2]);
}
else usage();
}
}
for (i=0; kw[i][0]!=NULL; i++)
{
if (strcmp(kw[i],_argv[1])==0)
{
switch (i)
{
case 0: help=1; break;
case 1: help=1; break;
case 2: help=1; break;
case 3: reset=1; break;
case 4: local=1; break;
case 5: local=1; break;
case 6: local=1; break;
case 7: show=1; break;
}
}
}
if (help==1) {usage(); exit (0);}
if (show==1) {SelectQueue(-1); exit (0);}
LoadList();
SortList();
GetEthernetNumber();
GetDefaultQueue();
if (local==1) {SelectQueue(-2); exit (0);}
if (reset==1) {SelectQueue(-3); exit (0);}
// given queue name
for (i=0;i<qcnt;i++)
{
if (strcmp(_argv[1],qlst[i])==0)
{
SelectQueue(i);
exit (0);
}
if ((qlst[i][0]=='Q')&&(qlst[i][1]=='_')&&strcmp(_argv[1],&qlst[i][2])==0)
{
SelectQueue(i);
exit (0);
}
}
printf("Queue \"%s\" is unknown\n",_argv[1]);
exit (1);
return;
}
main()
{
int i,j,k;
int WinPos;
int WinTop;
char result;
if (_argc>3) usage();
if (_argc>1) UseArg();
clrscr();
textcolor(LIGHTGRAY);
textbackground(BLACK);
LoadList();
SortList();
GetEthernetNumber();
GetDefaultQueue();
for (i=0;i<qcnt;i++)
{
j=strlen(qlst[i]);
k=strlen(qloc[i]);
if (j>MaxQueueNameLength ) MaxQueueNameLength =j;
if (k>MaxServerNameLength) MaxServerNameLength=k;
}
j=MaxQueueNameLength;
k=MaxServerNameLength;
WinPos=0;
WinTop=0;
result=' ';
ShowList();
while (result==' ')
{
result=ShowUpdate(WinTop,WinPos);
switch (result)
{
case 'H': WinPos=0;
result=' '; break;
case 'U': WinPos-=(MaxLines-1);
if (WinPos<0) WinPos=0;
result=' '; break;
case 'u': if (--WinPos<0) WinPos=qcnt-1;
result=' '; break;
case 'd': if (++WinPos>qcnt-1) WinPos=0;
result=' '; break;
case 'D': WinPos+=(MaxLines-1);
if (WinPos>qcnt-1) WinPos=qcnt-1;
result=' '; break;
case 'E': WinPos=qcnt-1;
result=' '; break;
case 'b': Banner=1-Banner;
result=' '; break;
case 's': SelectQueue(WinPos);
break;
case 'e': SelectQueue(-1);
break;
case '1': LptNum=1; result=' '; break;
case '2': LptNum=2; result=' '; break;
case '3': LptNum=3; result=' '; break;
case '?': clrscr(); usage(); break;
case 'X': clrscr(); break;
case '+': timeout++; if (timeout>900) timeout=0; result=' '; break;
case '-': timeout--; if (timeout<0) timeout=900; result=' '; break;
default : break;
}
if (WinPos<WinTop) WinTop=WinPos;
if ((WinPos-WinTop)>=MaxLines) WinTop=WinPos-MaxLines+1;
}
exit(0);
return(0);
}